package com.lmax.disruptor.custom.group;

import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.custom.demo.Trade;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.EventHandlerGroup;
import com.lmax.disruptor.dsl.ProducerType;
import com.lmax.disruptor.util.DaemonThreadFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main
{

    public static void main(final String[] args) throws InterruptedException
    {
        long beginTime = System.currentTimeMillis();
        int bufferSize = 1024;

        ExecutorService executor = Executors.newFixedThreadPool(8);

        WaitStrategy waitStrategy = new BusySpinWaitStrategy();
        EventFactory<Trade> eventFactory = Trade::new;
        Disruptor<Trade> disruptor = new Disruptor<>(eventFactory, bufferSize, DaemonThreadFactory.INSTANCE,
                ProducerType.SINGLE, waitStrategy);

//case1(disruptor);
//case2(disruptor);
        case3(disruptor);

        disruptor.start();
        int num = 6;
        CountDownLatch latch = new CountDownLatch(num);
        //生产者准备
        executor.submit(new TradePublisher(disruptor, latch, num));

//latch.await();//等待生产完成
//disruptor.shutdown();
//executor.shutdown();
        while (true)
        {
        }
    }

    public static void case1(final Disruptor disruptor)
    {
        //菱形操作
        //使用disruptor创建消费者组C1,C2
        // 1 : n
        EventHandlerGroup<Trade> handlerGroup = disruptor.handleEventsWith(
                new Handler1(), new Handler2());
        //声明在C1,C2完事之后执行JMS消息发送操作 也就是流程走到C3
        handlerGroup.then(new Handler3());
        //輸出結果：
        //handler1 set name:
        //handler2 set price:
        //handler3: name: h1 , price: 17.0;  instance: com.moudle.disruptorDemo.generate1.Trade@220a5c4d
    }

    public static void case2(final Disruptor disruptor)
    {
        //六边形操作
        Handler1 h1 = new Handler1();
        Handler2 h2 = new Handler2();
        Handler3 h3 = new Handler3();
        Handler4 h4 = new Handler4();
        Handler5 h5 = new Handler5();
        disruptor.handleEventsWith(h1, h2);
        disruptor.after(h1).handleEventsWith(h4);
        disruptor.after(h2).handleEventsWith(h5);
        disruptor.after(h4, h5).handleEventsWith(h3);
        //输出结果：
        //handler1 set name:
        //handler2 set price:
        //handler4 set addName:
        //handler5 set add price:
        //handler3: name: h1h4 , price: 20.0;  instance: com.moudle.disruptorDemo.generate1.Trade@5e6d6957
    }

    public static void case3(final Disruptor disruptor)
    {
        //顺序执行
        disruptor.handleEventsWith(new Handler1()).
                handleEventsWith(new Handler2()).
                handleEventsWith(new Handler3());
        //输出结果：
        //handler1 set name:
        //handler2 set price:
        //handler3: name: h1 , price: 17.0;  instance: com.moudle.disruptorDemo.generate1.Trade@331d6441
    }
}
